Shuffle the bits of the vmexit handler that run with EFLAGS.IF == 0 up
to the top. Otherwise we end up calling spin_lock() with interrupts
disabled, which can deadlock against the time-synchronization
rendezvous code.
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
perfc_incra(vmexits, exit_reason);
- if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
- local_irq_enable();
+ /* Handle the interrupt we missed before allowing any more in. */
+ if ( exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT )
+ vmx_do_extint(regs);
+
+ /* Now enable interrupts so it's safe to take locks. */
+ local_irq_enable();
if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
return vmx_failed_vmentry(exit_reason, regs);
break;
}
case EXIT_REASON_EXTERNAL_INTERRUPT:
- vmx_do_extint(regs);
+ /* Already handled above. */
break;
case EXIT_REASON_TRIPLE_FAULT:
hvm_triple_fault();